<template>
  <view class="dishwasher">
    <ProgramControl
      :control="baseControl"
      :flex-area-links="flexAreaLinks"
      :is-show-local="store.isSui"
      :custom-state-getter="customStateGetter"
      :custom-program-name-getter="customProgramNameGetter"
      :use-custom-action="showJumpLearningDetail"
      :notice-external-methods="noticeExternalMethods"
      :prevent-notice-action="preventNoticeAction"
      :custom-remote-hint="customRemoteHint"
      :custom-adjust-option-title="$t('Appliance.Dishwasher.AdjustOption.Button.Text')"
      @adjust="openAdjustParameter"
    >
      <template #aside-control>
        <AsideControl
          prevent
          :control="baseControl"
          :role="AsideRoles.Power"
          :overwrites="powerControlOverwrites"
          @power-change="onPowerChange"
        />
      </template>
      <template #tabs-extra>
        <TrackButton track-id="Dishwasher.Sui.ProgramList.Button.Text" :type="TrackType.ApplianceDetail">
          <view
            v-if="store.isSui && store.hasNotSettedFavorite"
            class="sui-dot"
            :class="{ disabled: !isPowerOn || isOffline === true }"
          ></view>
          <TextButton
            v-if="store.isSui"
            size="small"
            :disabled="!isPowerOn || isOffline === true"
            @click="openEditFavoriteProgram"
            class="programList-btn"
            >{{ $t('Dishwasher.Sui.ProgramList.Button.Text') }}</TextButton
          >
        </TrackButton>
      </template>
      <template #state-view-prefix>
        <view class="run-phase" v-if="isShowPhase">
          <text class="phase-value" v-if="isStorage">{{ currentRunPhase?.valueStorage }}</text>
          <text class="phase-value" v-else-if="isEcoDry">{{ currentRunPhase?.valueEcoDry }}</text>
          <text class="phase-value" v-else>{{ currentRunPhase?.value }}</text>
        </view>
        <view class="suspend-tips" v-if="isShowSuspendTips">{{ $t('Appliance.Dishwasher.SuspendTips.Text') }}</view>
      </template>
      <template #state-view-suffix>
        <view class="storage-phase" v-if="isShowStorage">
          <view class="storage-time">{{ storageActiveTimeValue }}</view>
          <progress
            class="Dishwasher-view-progress-style"
            backgroundColor="#E9E9ED"
            stroke-width="6"
            active
            :percent="storagePercent"
          ></progress>
        </view>
      </template>
      <template #custom-action>
        <block v-if="showJumpLearningDetail">
          <ActionButton
            :disabled="isOffline === true"
            :plain-disabled="startDisabled"
            :text="$t('Appliance.ViewDetail.Button.Text')"
            @click="toLearningDetail(LearningViewEntry.ActionBar)"
          />
        </block>
      </template>

      <AdjustParameterModal
        v-model:show="adjustParameterVisible"
        :control="baseControl"
        :custom-program-name-getter="customProgramNameGetter"
        :no-prefix="!showFlexSprayPartition"
      >
        <template #prefix>
          <ParameterCard :title="$t('Dishwasher.customProgram.AdjustParams.Label.Text')">
            <view class="flex-spray">
              <view class="title">{{ control.store.flexSprayAdjustTitle }}</view>
              <view class="flex-spray-des">
                <text>{{ $t('Dishwasher.Flexspray.AdjustParams.Des.Before.Text') }}</text>
                <text class="flex-spray-highlight">{{ $t('Dishwasher.Flexspray.AdjustParams.Des.Middle.Text') }}</text>
                <text>{{ $t('Dishwasher.Flexspray.AdjustParams.Des.Last.Text') }}</text>
              </view>
              <view class="page-img-box">
                <PartitionView
                  :type="store.isVirtualAppliance ? 'flexSpray' : 'adjust'"
                  :haId="store._datasource.haId"
                  :programKey="store.currentProgramKey"
                  :programName="store.currentProgramName"
                  :flex-spray-list="flexSprayList"
                />
              </view>
            </view>
          </ParameterCard>
        </template>
      </AdjustParameterModal>

      <OrderModal
        v-model:show="orderModalVisible"
        :control="baseControl"
        :custom-adjust-option-title="$t('Appliance.Dishwasher.AdjustOption.Button.Text')"
        :custom-select-time-back-texts="$t('Appliance.Dishwasher.AdjustOption.Button.Text')"
        :selected-program-disabled="selectedProgramDisabled"
      />

      <ShutdownTips v-model:show="showShutdownTips" :control="control" @confirm="confirmShutdown" />

      <FlexSpray
        v-model:show="isShowFlexSpray"
        :control="control"
        :temp-custom-flex-spray-list="tempCustomFlexSprayList"
        @open-adjust-params="openAdjustParameter"
      />

      <EditFavoriteProgram v-model:show="isShowEditFavoriteProgram" :control="control" />

      <CustomProgram
        v-model:show="isShowCustomProgram"
        :control="control"
        :flex-spray-list="flexSprayList"
        :show-flex-spray-partition="showFlexSprayPartition"
      />

      <LearningView
        v-model:show="learningViewVisible"
        ref="learningRef"
        :scene="learningViewScene"
        :entry="learningViewEntry"
        :control="control"
      />
    </ProgramControl>

    <!-- 固件升级成功 -->
    <SuccessAcknowledge v-if="otaHelper" :helper="otaHelper" />
  </view>
</template>

<script setup lang="ts">
import FlexSpray from './flexSpray/flexSpray.vue'
import ParameterCard from '../components/parameterCard.vue'
import PartitionView from './partitionView.vue'
import EditFavoriteProgram from './editFavoriteProgram/editFavoriteProgram.vue'
import CustomProgram from './customProgram/customProgram.vue'
import TrackButton from '@/dataReport/components/TrackButton.vue'
import { trackEvent, TrackType } from '@/dataReport/tracks'
import { useScrollProvider } from '@/utils/composition/useScroll'
// 注意：请勿将onShareAppMessage删除
import { onPageScroll, onShareAppMessage } from '@dcloudio/uni-app'
import ProgramControl, { type CustomRemoteHintOptions } from '../view/control/programControl.vue'
import type { FlexAreaLink } from '../view/control/components/FlexArea.vue'
import OrderModal from '../view/order/index.vue'
import AdjustParameterModal from '../view/adjustParameterModal.vue'
import {
  BSH_COMMOM_PROGRAM_FAVORITE_001,
  BSH_COMMOM_PROGRAM_FAVORITE_002,
  DISHWASHER_STATUS_PHASE_DRYING,
  DISHWASHER_STATUS_PHASE_MAINWASH,
  DISHWASHER_STATUS_PHASE_NONE,
  DISHWASHER_STATUS_PHASE_PREWASH,
  DISHWASHER_STATUS_PHASE_RINSE,
  OPERATION_STATES,
  POWER_STATES,
  REMOTE_CONTROL_ACTIVE,
  SETTING_REMOTE_CONTROL_LEVEL,
  DISHWASHER_STORAGEFUNCTIONACTIVE,
  DISHWASHER_VENTEDSTORAGEACTIVE,
} from '@/constants/Command'
import { useI18n } from 'vue-i18n'
import type { BaseController } from '@/controller/BaseAppliance/definition'
import { AsideRoles, useControlState } from '@/controller/BaseAppliance/useControl'
import AsideControl from '../view/control/components/AsideControl.vue'
import { useFlexSpray } from './flexSpray/useFlexSpray'
import { useStorage } from './storage/useStorage'
import { callEventSender, toPage, useUniEvent } from '@/utils/mpHelper'
import TextButton from '@/common/textButton.vue'
import type { CustomConfigGetter, StateViewConfig } from '../view/stateView.vue'
import ActionButton from '@/common/actionButton/actionButton.vue'
import LearningView from './learning/learning.vue'
import { LearningViewEntry, LearningViewScene } from './learning/constants'
import { LearningProgramKey } from '@/controller/Dishwasher/Learning/constants'
import type { DishwasherController } from '@/controller/Dishwasher/definition'
import { safeTrack } from '@/dataReport/dataReportUtil'
import { useShutdown } from '../view/powerShutdown/useShutdown'
import ShutdownTips from '../view/powerShutdown/shutdownTips.vue'
import type { Notice } from '@/types/notice'
import { DishwasherProgramDownload, NoticePreventActionInvoked } from '@/constants/UniEventKeys'
import type { ToParameterSettingsPayload } from '../settings/applianceSettingsView.vue'
import { checkApplianceRelatedFlexAreaAccessable } from '@/controller/common/ErrorHandler/validator'
import SuccessAcknowledge from '../settings/ota/modals/successAcknowledge.vue'
import { useInhouseOtaHelper } from '../view/useOtaHelper'
import { NoticeModalAcknowledge } from '@/constants/UniEventKeys'

const { setScrollTop } = useScrollProvider()
onPageScroll(({ scrollTop }) => setScrollTop(scrollTop))

const props = defineProps<{
  control: DishwasherController.Control
}>()

const i18n = useI18n()

const control = props.control
const { store } = control
const baseControl = control as BaseController.Control
const controlState = useControlState(control)
const { isOffline, isPowerOn, controlFlexLinksDisabled, startDisabled, orderDisabled, showControlView } = controlState

/**
 * OTA升级
 */
const otaHelper = useInhouseOtaHelper(control)

/**
 * 精控强洗
 */
const {
  flexSprayList,
  tempCustomFlexSprayList,
  getFlexSprayDataFun,
  getCustomSprayDataFun,
  transformCutomToIndividual,
  listenMessages,
} = useFlexSpray(control)
watchEffect(() => {
  props.control.store.flexSprayList = flexSprayList.value || []
})
// 注释：control.worker为了等detail接口加载完以后才会进行下面操作
control.worker.onLoad(async (query: any) => {
  // 虚拟体验进入页面需要先获取cls数据，因为不会触发watch需要特殊处理
  if (store.flexSpraySupported || store.isVirtualAppliance) {
    getFlexSprayDataFun()
    getCustomSprayDataFun()
    if (!store.isVirtualAppliance) listenMessages()
  }
})

control.worker.onShow(async () => {
  if (!store.isOffline && store.detail?.installable && showControlView.value) {
    control.store.loadAllPrograms()
  }
})

/**
 * 断电处理
 */
const { powerControlOverwrites, onPowerChange, showShutdownTips, confirmShutdown } = useShutdown(control)

/**
 * 通知栏操作
 */
const noticeExternalMethods = {
  openLearningFeedback,
}
async function preventNoticeAction(notice: Notice) {
  // 需要切换远程控制等级 阻止默认action事件
  return shouldChangeRemoteControlLevel(notice)
}

// SMM类型PDC家电 需要切换远程控制等级
function shouldChangeRemoteControlLevel(notice: Notice) {
  return control.store.isSMM && notice.key === REMOTE_CONTROL_ACTIVE
}
// 打开参数设置——远程控制等级设置页
function openControlLevelSettings() {
  const { haId, type, vib } = control.store._datasource
  const payload: ToParameterSettingsPayload = {
    haId,
    type,
    vib,
    key: SETTING_REMOTE_CONTROL_LEVEL,
    isVirtual: control.store.isVirtualAppliance,
  }
  toPage('/pages/appliance/settings/parameterSettings', payload)
}

useUniEvent(NoticePreventActionInvoked, (notice: Notice) => {
  // 切换远程控制等级
  if (shouldChangeRemoteControlLevel(notice)) {
    openControlLevelSettings()
  }
})

function customRemoteHint(): CustomRemoteHintOptions | undefined {
  if (control.store.isSMM && !control.store.remoteStart) {
    return {
      title: i18n.t('Appliance.RemoteHint.HowToEnableRemoteStart.Text'),
      dismissText: i18n.t('APP.Common.GotIt.Text'),
      cancelText: i18n.t('Appliance.RemoteHint.ToEnablePermanent.Text'),
      stepsGetter: (steps) => [steps[0]],
      onConfirm: () => {},
      onCancel: () => openControlLevelSettings(),
    }
  }
}

watch(
  () => store.detail,
  (detail) => {
    if (!detail) return
    if (!store.isVirtualAppliance && store.flexSpraySupported && detail?.programKey === BSH_COMMOM_PROGRAM_FAVORITE_001)
      getFlexSprayDataFun()
  }
)

watch(
  () => store._datasource.settings,
  () => {
    if (store.flexSpraySupported && !store.isVirtualAppliance) getCustomSprayDataFun()
  }
)

/**
 * AI智洗
 */
const learningRef = ref<InstanceType<typeof LearningView> | null>(null)
// 是否显示AI智洗程序查看详情 按钮【当前选中AI智洗 且 首次使用】
const showJumpLearningDetail = computed(() => store.learningProgramSelected && !store.learningUsed)
const learningViewVisible = ref(false)
const learningViewScene = ref<LearningViewScene | null>(null)
const learningViewEntry = ref<LearningViewEntry>(LearningViewEntry.ActionBar)
// 打开详情页
async function toLearningDetail(entry: LearningViewEntry) {
  await store.setCurrentProgram(LearningProgramKey)
  learningViewScene.value = LearningViewScene.Detail
  learningViewEntry.value = entry
  nextTick(() => {
    learningViewVisible.value = true
    // 延迟设置 防止控制按钮闪烁 以及详情页不再显示流程介绍
    setTimeout(() => {
      // 设为非首次使用
      store.setLearningUsed(true)
    }, 500)
  })
}
function openLearningFeedback() {
  learningRef.value?.openFeedbackView()
}

const flexSprayName = computed(() =>
  store._datasource.brand === 'BOSCH'
    ? i18n.t('Appliance.FlexSpray.BOSCH.Button.Text')
    : i18n.t('Appliance.FlexSpray.SIEMENS.Button.Text')
)
/**
 * Flex Area Links
 */
const flexAreaLinks = computed(() => {
  if (!store._datasource.loaded) return []

  const links: FlexAreaLink[] = []

  if (store.learningSupported) {
    links.push({
      icon: '/pages/appliance/static/learning/AI.png',
      name: i18n.t('Appliance.LearningProgram.Button.Text'),
      trackCode: 'Appliance.LearningProgram.Button.Text',
      disabled: isOffline.value === true,
      plainDisabled: controlFlexLinksDisabled.value,
      onClick: () =>
        checkApplianceRelatedFlexAreaAccessable(props.control) && toLearningDetail(LearningViewEntry.FlexArea),
    })
  }

  links.push({
    icon: '/pages/appliance/static/DelayStart.png',
    name: i18n.t('Appliance.OrderWash.Button.Text'),
    trackCode: 'Appliance.OrderWash.Button.Text',
    disabled: isOffline.value === true,
    plainDisabled: orderDisabled.value,
    onClick: () => checkApplianceRelatedFlexAreaAccessable(props.control) && openOrderModal(),
  })

  if (store.flexSpraySupported) {
    links.push({
      icon: '/pages/appliance/static/iTurboWash.png',
      name: flexSprayName.value,
      trackCode: 'Appliance.FlexSpray.Button.Text',
      disabled: isOffline.value === true,
      plainDisabled: controlFlexLinksDisabled.value,
      onClick: () => checkApplianceRelatedFlexAreaAccessable(props.control) && showFlexSprayModal(),
    })
  }

  links.push({
    icon: '/pages/appliance/static/Consumable.png',
    name: i18n.t('Appliance.ConsumablesService.Button.Text'),
    trackCode: 'Appliance.ConsumablesService.Button.Text',
    onClick: openConsumablesService,
  })

  if (store.detail?.installable) {
    links.push({
      icon: '/pages/appliance/static/ProgramDownload.png',
      name: i18n.t('Appliance.ProgramDownload.Button.Text'),
      trackCode: 'Appliance.ProgramDownload.Button.Text',
      disabled: isOffline.value === true,
      plainDisabled: controlFlexLinksDisabled.value,
      onClick: () => checkApplianceRelatedFlexAreaAccessable(props.control) && jumpProgramDownload(),
    })
  }

  if (isExistCustom.value) {
    links.push({
      icon: '/pages/appliance/static/CustomProgram.png',
      name: i18n.t('Appliance.Custom.Button.Text'),
      trackCode: 'Appliance.Custom.Button.Text',
      disabled: isOffline.value === true,
      plainDisabled: controlFlexLinksDisabled.value,
      onClick: () => checkApplianceRelatedFlexAreaAccessable(props.control) && showCustomModal(),
    })
  }

  return links
})

/**
 * 跳转耗材服务
 */
function openConsumablesService() {
  toPage('/pages/consumablesService/consumablesService', {
    vib: store._datasource.vib,
  })
}

/**
 * 调节参数
 */
const adjustParameterVisible = ref(false)
const showFlexSprayPartition = computed(() => {
  // 虚拟家电在Ready状态下 始终显示精控强洗
  if (store.isVirtualAppliance) return showControlView.value

  // 支持精控强洗 且 当前程序非AI智洗 且为Ready状态
  return store.flexSpraySupported && !store.learningProgramSelected && showControlView.value
})

async function openAdjustParameter() {
  if (
    (store.flexSpraySupported && store.currentProgramKey !== BSH_COMMOM_PROGRAM_FAVORITE_001) ||
    store.isVirtualAppliance
  ) {
    transformCutomToIndividual()
  }
  // 埋点仅本次启动跳转
  safeTrack(() => {
    trackEvent('Dishwasher.Flexspray.OnlyOneStart.Button.Text', {}, TrackType.ApplianceDetail)
  })
  adjustParameterVisible.value = true
}

/**
 * 预约
 */
const orderModalVisible = ref(false)
function openOrderModal() {
  orderModalVisible.value = true
}

/**
 * 跳转程序下载页面
 */
useUniEvent(DishwasherProgramDownload, () => openAdjustParameter())
async function jumpProgramDownload() {
  const res = await toPage('/pages/appliance/Dishwasher/programDownload/programDownload', {
    haId: store._datasource.haId,
    vib: store._datasource.vib,
    brand: store._datasource.brand,
    type: store._datasource.type,
    isVirtual: store.isVirtualAppliance,
  })
  callEventSender(res.eventChannel, 'control', control)
}

/**
 * sui
 */
const isShowEditFavoriteProgram = ref(false)
const selectedProgramDisabled = computed(
  () =>
    store.isSui && [BSH_COMMOM_PROGRAM_FAVORITE_001, BSH_COMMOM_PROGRAM_FAVORITE_002].includes(store.currentProgramKey)
)
function openEditFavoriteProgram() {
  isShowEditFavoriteProgram.value = true
}

/**
 * cls
 */
const isShowFlexSpray = ref(false)
function showFlexSprayModal() {
  isShowFlexSpray.value = true
}

/**
 * 抑菌储存
 */
const { isShowStorage, storagePercent, storageActiveTimeValue } = useStorage(control)
const finishedBtnText = computed(() => (control.store.powerState === POWER_STATES.ON ? '关机' : '开机'))
const customStateGetter: CustomConfigGetter = (currentState, defaultGetter) => {
  let config: StateViewConfig = defaultGetter(currentState)
  if (!isShowStorage.value) return config
  config = {
    title: i18n.t('Appliance.StateView.Run.Title'),
    contents: [],
    actions: [{ name: finishedBtnText.value, presetEvent: 'power-off' }],
  }
  return config
}

watch(
  () => control.store.powerState,
  () => {
    if (!store.isVirtualAppliance && isShowStorage.value) {
      control.remote.loadApplianceDetail()
    }
    getFlexSprayDataFun()
  }
)
// 立即联系
useUniEvent(NoticeModalAcknowledge, (options: any) => {
  if ([DISHWASHER_STORAGEFUNCTIONACTIVE, DISHWASHER_VENTEDSTORAGEACTIVE].includes(options?.key)) {
    storageActiveTimeValue.value = i18n.t('Dishwasher.BacteriostatStorage.StorageCloes.WaitTips.Text')
  }
})

/**
 * 自定义
 */
const isExistCustom = computed(() => store.hasFavoriteFunction && !store.isSui)
function customProgramNameGetter(programKey: string, programName: string, isCurrent: boolean) {
  return isCurrent && !!baseName.value ? `自定义-${baseName.value}` : programName
}
const baseName = computed(() => {
  if (isExistCustom.value && store.customProgramSelected) {
    return store.customBaseName
  }
  return ''
})
const isShowCustomProgram = ref(false)
function showCustomModal() {
  if (store.flexSpraySupported) {
    getFlexSprayDataFun()
  }
  isShowCustomProgram.value = true
}

/**
 * 运行阶段文字添加
 */
const WASH_PHASE_HINT = [
  {
    key: DISHWASHER_STATUS_PHASE_NONE,
    value: '',
  },
  {
    key: DISHWASHER_STATUS_PHASE_PREWASH,
    value: '预洗：冲刷中，可以继续添加餐具',
  },
  {
    key: DISHWASHER_STATUS_PHASE_MAINWASH,
    value: '主洗：高温洗涤中，小心开门烫伤',
  },
  {
    key: DISHWASHER_STATUS_PHASE_RINSE,
    value: '漂洗：高温漂洗中，小心开门烫伤',
  },
  {
    key: DISHWASHER_STATUS_PHASE_DRYING,
    value: '烘干：烘干中，程序完成三十分钟后取出餐具，烘干效果更好',
    valueStorage: '烘干：烘干中，程序完成后，可抑菌存储96小时',
    valueEcoDry: '智能开门烘干中：温度较高，程序完成前请勿取出餐具',
  },
]
type RunPhaseType = {
  key: string
  value: string
  valueStorage?: string
  valueEcoDry?: string
}
const currentRunPhase = computed<RunPhaseType | null>(() => {
  if (store.operationState !== OPERATION_STATES.RUN) return null

  return (WASH_PHASE_HINT.find((item) => item.key === store.programPhase) as RunPhaseType) || null
})
const isStorage = computed(
  () => control.store.isStorageOption && currentRunPhase.value?.key === DISHWASHER_STATUS_PHASE_DRYING
)
const isEcoDry = computed(
  () => control.store.isActiveEcoDry && currentRunPhase.value?.key === DISHWASHER_STATUS_PHASE_DRYING
)
const isShowPhase = computed(() => store.operationState === OPERATION_STATES.RUN && !!currentRunPhase.value?.value)

/**
 * 停止运行显示用户提示
 */
const isShowSuspendTips = computed(() => store.operationState === OPERATION_STATES.ABORTING)
</script>

<style scoped lang="less">
@import '../view/control/control.less';
/* 自定义程序 */
.local-icon {
  font-family: PingFang SC;
  font-style: normal;
  height: 32rpx;
  text-align: center;
  line-height: 32rpx;
  background-color: var(--primary-color);
  color: #fff;
  font-weight: 600;
  font-size: 20rpx;
  position: absolute;
  top: -6rpx;
  left: -6rpx;
  padding: 0 4rpx;
}
/* 精控强洗 */
.flex-spray {
  font-family: 'PingFang SC';
  font-style: normal;
  .title {
    font-weight: 500;
    font-size: 28rpx;
    line-height: 40rpx;
    color: var(--dark-color);
    padding: 0 24rpx;
  }
  .flex-spray-des {
    font-weight: 400;
    font-size: 24rpx;
    line-height: 34rpx;
    color: var(--dark-color);
    margin-top: 16rpx;
    margin-bottom: 8rpx;
    padding: 0 24rpx;
    .flex-spray-highlight {
      font-weight: 500;
      color: var(--primary-color);
    }
  }
}
.programList-btn {
  margin-right: 32rpx;
  display: block;
}
.storage-phase {
  .storage-time {
    font-weight: 500;
    font-size: 36rpx;
    line-height: 50rpx;
    color: var(--dark-color);
    margin-bottom: 12rpx;
  }
}
.page-img-box {
  width: 100%;
  height: 652rpx;
  padding: 24rpx 24rpx 0rpx;
  background-color: #f4f4f6;
  box-sizing: border-box;
  position: relative;
}
.run-phase {
  font-family: PingFang SC;
  font-style: normal;
  margin-top: -22rpx;
  font-size: 28rpx;
  font-weight: 400;
  color: var(--dark-color);
  margin-bottom: 48rpx;
}
.suspend-tips {
  font-family: PingFang SC;
  font-style: normal;
  font-size: 28rpx;
  font-weight: 400;
  color: var(--dark-color);
  margin-top: -18rpx;
  margin-bottom: 40rpx;
}
// 小红点
.sui-dot {
  width: 8rpx;
  height: 8rpx;
  border-radius: 50%;
  background-color: #ff453a;
  position: absolute;
  right: 28rpx;
  top: 16rpx;
  &.disabled {
    opacity: 0.4;
  }
}
</style>
